package com.portal.settings;

import org.apache.commons.lang3.StringUtils;

import javax.sql.DataSource;
import java.util.*;

public class SettingsManager {

    private String createSql = "INSERT INTO `${tableName}` (`${name}`, `${group}`, `${content}`, `${description}`, `${virtual_region}`,`${gmt_create}`,`${gmt_modified}`) VALUES (?, ?, ?, ?,?,CURRENT_TIMESTAMP(3),CURRENT_TIMESTAMP(3))";
    private String queryAllSql = "select `id`, `${name}`, `${group}`  as `group`, `${content}`,`${gmt_modified}` as gmtModified, `${virtual_region}` from `${tableName}` order by `${gmt_modified}` asc limit 10000";
    private String queryDeltaSql = "select `id`, `${name}`, `${group}`  as `group`, `${content}`,`${gmt_modified}` as gmtModified, `${virtual_region}` from `${tableName}` where `${gmt_modified}` > ? order by `${gmt_modified}` asc limit 10000";
    private String queryIdExistsSql = "select id from `${tableName}` where `${name}`=? and `${group}`=? and `${virtual_region}`=? limit 1";

    private DataSource dataSource;

    private SettingsTableDefine settingsTableDefine;

    private Map<String, String> sqlParam = new HashMap<>();

    private boolean enableRegion;

    public SettingsManager(SettingsTableDefine settingsTableDefine) {
        this.setSettingsTableDefine(settingsTableDefine);
    }

    public boolean isEnableRegion() {
        return enableRegion;
    }

    public void setEnableRegion(boolean enableRegion) {
        this.enableRegion = enableRegion;
    }

    public int create(Settings.SettingsRow settingsRow) {
        Objects.requireNonNull(settingsRow);
        Objects.requireNonNull(StringUtils.trimToNull(settingsRow.getContent()));
        Objects.requireNonNull(StringUtils.trimToNull(settingsRow.getGroup()));
        Objects.requireNonNull(StringUtils.trimToNull(settingsRow.getName()));

        return getJdbcTemplate().update(createSql, settingsRow.getName(), settingsRow.getGroup(), settingsRow.getContent(), settingsRow.getDescription(), settingsRow.getVirtualRegion());
    }

    public List<Settings.SettingsRow> queryAll() {
        return getJdbcTemplate().query(queryAllSql, new BeanPropertyRowMapper<>(Settings.SettingsRow.class));
    }

    public List<Settings.SettingsRow> queryDelta(Date lastDate) {
        return getJdbcTemplate().query(queryDeltaSql, new Object[]{lastDate}, new BeanPropertyRowMapper<>(Settings.SettingsRow.class));
    }

    public Long queryIdExists(String name, String group,String virtualRegion) {
        List<Long> queryResult = getJdbcTemplate().query(queryIdExistsSql, new Object[]{name, group,virtualRegion}, SingleColumnRowMapper.newInstance(Long.class));
        Long id = DataAccessUtils.singleResult(queryResult);
        return id;
    }





    public SettingsManager setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        return this;
    }

    public SettingsManager setSettingsTableDefine(SettingsTableDefine settingsTableDefine) {
        this.settingsTableDefine = settingsTableDefine;
        this.sqlParam = new HashMap<>();
        this.sqlParam.put("tableName", settingsTableDefine.getTableName());
        this.sqlParam.put("name", settingsTableDefine.getFieldName());
        this.sqlParam.put("group", settingsTableDefine.getFieldGroup());
        this.sqlParam.put("content", settingsTableDefine.getFieldContent());
        this.sqlParam.put("description", settingsTableDefine.getFieldDescription());
        this.sqlParam.put("gmt_create", settingsTableDefine.getFieldGmtCreate());
        this.sqlParam.put("gmt_modified", settingsTableDefine.getFieldGmtModified());
        this.sqlParam.put("virtual_region", settingsTableDefine.getFieldRegion());

        this.createSql = formatSql(createSql, sqlParam);
        this.queryAllSql = formatSql(queryAllSql, sqlParam);
        this.queryDeltaSql = formatSql(queryDeltaSql, sqlParam);
        this.queryIdExistsSql = formatSql(queryIdExistsSql, sqlParam);
        return this;
    }

    private JdbcTemplate getJdbcTemplate() {
        return SettingsJdbcUtils.getJdbcTemplate(dataSource);
    }


    private String formatSql(String sqlTemplate, Map<String, String> sqlParam) {
        StringSubstitutor substitutor = new StringSubstitutor(sqlParam);
        return substitutor.replace(sqlTemplate).replace("\n", " ");
    }

}
